package com.os.opencv.java.chapter7;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.util.Random;

public class ConnectedComponents {

    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        //读取图像并在屏幕上显示
        Mat src = Imgcodecs.imread("/Users/matt/Pictures/xigua.jpg");
        HighGui.imshow("src", src);
        HighGui.waitKey(0);

        //将图像转换为灰度图并二值化
        Mat gray = new Mat();
        Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
        //取反操作
        Core.bitwise_not(gray, gray);
        Mat binary = new Mat();
        Imgproc.threshold(gray, binary, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);

        //在屏幕上显示二值图
        HighGui.imshow("binary", binary);
        HighGui.waitKey(0);

        //标记连通域
        Mat labels = new Mat(src.size(), CvType.CV_32S);
        int num = Imgproc.connectedComponents(binary, labels, 8, CvType.CV_32S);

        //定义颜色数组，用于不同联通区
        Scalar[] colors = new Scalar[num];

        //随机生成颜色
        Random rd = new Random();
        for(int i=0; i<num; i++){
            int r = rd.nextInt(256);
            int g = rd.nextInt(256);
            int b = rd.nextInt(256);
            colors[i] = new Scalar(r, g, b);
        }

        //标记各联通区域，dst为用于标记的图像
        Mat dst = new Mat(src.size(), src.type(), new Scalar(255,255,255));
        int width = src.cols();
        int height = src.rows();
        for(int i=0; i<height; i++){
            for(int j=0; j<width; j++){
                //获取标签号
                int label = (int) labels.get(i, j)[0];

                //黑色背景色不变
                if(label == 0){
                    continue;
                }

                //根据标签号设置颜色
                double[] val = new double[3];
                val[0] = colors[label].val[0];
                val[1] = colors[label].val[1];
                val[2] = colors[label].val[2];
                dst.put(i, j, val);
            }
        }

        //在屏幕上显示最后结果
        HighGui.imshow("labelled", dst);
        HighGui.waitKey(0);

        System.exit(0);
    }
}
